﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Bling.DSL;
using Bling.WPF;
using Bling.WPF.Custom;
using Bling.Core;

using Bling.Graphics;
using Bling.Util;
using Bling.Reactive;

namespace Bling.Tutorial {
  public class Menus : Canvas {
    public Menus() {
      CanvasBl Self = this;
      Self.Background = new ColorBl(.9, .9, .9);
      Self.Size = 300d;

      var Machine = new Machine() { Name = "MenuState" };
      var Level1 = Machine.MakeState("Level1");
      var Level2 = Machine.MakeState("Level2");
      var Idle = Self.Mouse.IsDirectlyOver & TimeSpan.FromMilliseconds(2000).AlarmUI();
      Level1[Idle] = Machine.Initial; Level1[Self.Mouse.Leave] = Machine.Initial;
      Level2[Idle] = Level1;          Level2[Self.Mouse.Leave] = Machine.Initial;

      var lbl = new LabelBl(Self) {
        Content = "Initial",
        LeftBottom = new Double2Bl(0, Self.Height),
        Foreground = Machine.Initial.Condition(Brushes.Red.Bl(), Brushes.Black.Bl()),
      };
      lbl = new LabelBl(Self) {
        Content = "Level-1",
        LeftBottom = lbl.RightBottom,
        Foreground = Level1.Condition(Brushes.Red.Bl(), Brushes.Black.Bl()),
      };
      lbl = new LabelBl(Self) {
        Content = "Level-2",
        LeftBottom = lbl.RightBottom,
        Foreground = Level2.Condition(Brushes.Red.Bl(), Brushes.Black.Bl()),
      };

      /* these two lines... */
      var L1Clock = Level1.Animate(a => a.Tween(d => d.Ease.Quad. In).Duration(400));
      var L2Clock = Level2.Animate(a => a.Tween(d => d.Ease.Quad.Out).Duration(400));
      /* are equivalent to...
      DoubleBl L1Clock = this.Property(DoubleBl.Zero);
      DoubleBl L2Clock = this.Property(DoubleBl.Zero);
      L1Clock[Level1.In].Animate().Duration(400).To = 1d;
      L1Clock[Level1.Out].Animate().Duration(400).To = 0d;
      L2Clock[Level2.In].Animate().Duration(400).To = 1d;
      L2Clock[Level2.Out].Animate().Duration(400).To = 0d;
      */


      var Center = new EllipseBl(Self) {
        CenterPosition = Self.CenterSize,
        ZIndex = (L2Clock > 0).Condition(0, 5.Bl()),
        Size = 50,
        Fill = (L1Clock + L2Clock).Lerp(Colors.Black.Bl(), Colors.White.Bl()),
      };
      Machine.Initial[Center.Mouse.Enter] = Level1;
      Machine.Initial[Center.Mouse.Down] = Level1;
      Level1[Center.Mouse.Down] = Machine.Initial;
      Level2[Center.Mouse.Down] = Machine.Initial;



      var SelectedIndex = this.Property(0.Bl());
      int N = 14;
      DoubleBl dN = N;
      Func<DoubleBl, DoubleBl, Double2Bl> F = (i, d) => {
        DoubleBl M = (i % N);
        M = M / N;
        return Self.CenterSize + 100d * M.PI2.SinCos * d;
      };
      for (int i = 0; i < N; i++) {
        var Item = new EllipseBl(Self) {
          CenterPosition = Self.CenterSize + 100d * (i/dN).PI2.SinCos * L1Clock,
          ZIndex = (i == SelectedIndex).Condition(3.Bl(), 2.Bl()),
          Fill = i.SelectColor(),
          ToolTip = "Category " + i,
          Visibility = L1Clock > 0d | SelectedIndex == i,
        };
        Item.Size = 50 * Item.IsMouseOver.Condition(1.2d, L2Clock.Lerp(1d, (i == SelectedIndex).Condition(1.2d.Bl(), 1d.Bl())));
        Level1[Item.Mouse.Down] = Level2;
        Level2[Item.Mouse.Down] = Level1;
        SelectedIndex[Item.Mouse.Down] = i;

        var j = SelectedIndex + L2Clock.Lerp(0d.Bl(), (DoubleBl)i);
        var Item0 = new EllipseBl(Self) {
          CenterPosition = Self.CenterSize + 100d * (j / dN).PI2.SinCos,
          Fill = 0.5.Bl().Lerp(SelectedIndex.SelectColor(), i.SelectColor()),
          ToolTip = "Subcategory ".Bl() + SelectedIndex + ":" + i.Bl(),
          Visibility = L2Clock > 0d,
        };
        Item0.Size = 50 * (Item0.IsMouseOver).Condition(L2Clock.Lerp(1d, 1.2d.Bl()), 1d);
      }
      Machine.Activate();
    }
  }
}